home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / awe2-0_1.lha / awe2-0.1 / Src / RCS / HardwareContext-mips.cc,v < prev    next >
Text File  |  1989-10-24  |  7KB  |  248 lines

  1. head     1.1;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    grunwald:1.1; strict;
  6. comment  @@;
  7.  
  8.  
  9. 1.1
  10. date     89.10.24.13.08.34;  author grunwald;  state Exp;
  11. branches ;
  12. next     ;
  13.  
  14.  
  15. desc
  16. @@
  17.  
  18.  
  19.  
  20. 1.1
  21. log
  22. @Initial revision
  23. @
  24. text
  25. @// This may look like C code, but it is really -*- C++ -*-
  26. // 
  27. // Copyright (C) 1988 University of Illinois, Urbana, Illinois
  28. //
  29. // written by Dirk Grunwald (grunwald@@cs.uiuc.edu)
  30. //
  31. #include "HardwareContext.h"
  32. #include "HardwareContextP.h"
  33. #include "CpuMultiplexor.h"
  34. #include "Thread.h"
  35. #include "assert.h"
  36. #include <stream.h>
  37.  
  38. //
  39. //    Many machines have the same (or very similar) stack format.
  40. //    The 68K & 32K are examples of such machines.
  41. //
  42. //    The const *registers* defines the number of additional longwords
  43. //    needed on the stack past the last frame pointer. This value needs
  44. //    to jibe with the one in HardwareContext-<arch>.s.
  45. //
  46.  
  47. const long MagicStackMarker = 0x464f4f20;    // this says 'FOO '
  48.  
  49. #define ALL_REGISTERS \
  50. asm (" " : : :\
  51.      "$0", "at", "v0", "v1",\
  52.      "a0", "a1", "a2", "a3", \
  53.      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",\
  54.      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",\
  55.      "t8", "t9",\
  56.      "k0", "k1", "gp", "sp", "fp", "ra",\
  57.      "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",\
  58.      "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",\
  59.      "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",\
  60.      "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31" );\
  61.  
  62.  
  63. static int expectedBytesSavedInContext = 112;
  64. static int numberOfBytesSavedInContext = 0;
  65. static int numberOfQuadsSavedInContext = 0;
  66.  
  67. HardwareContext::HardwareContext (int check, unsigned size)
  68. {
  69.     checkStackLimits = check;
  70.  
  71.     stackBase = 0;
  72.     stackEnd = 0;
  73.     stackMax = 0;
  74.     stackSize = 0;
  75.     stackCheck = 0;
  76.     stackMallocAt = 0;
  77.  
  78.     if (size > 0) {
  79.     stackSize = size;
  80.     stackMallocAt = new void *[ stackSize ];
  81.     //
  82.     // stackBase should point to the first writeable cell of the
  83.     // new stack.
  84.     //
  85.     stackEnd = stackMallocAt;
  86.     stackBase = &stackMallocAt[stackSize-1];
  87.     }
  88.     else {
  89.     //
  90.     // Have the main process figure out how many registers
  91.     // (actually, Quads) are pushed when we save an entire context.
  92.     // Do this by calling magicSwitchTo with itself. This has
  93.     // the side-effect of storing fp & sp in the context.
  94.     //
  95.     magicSwitchTo(this);
  96.     numberOfBytesSavedInContext = (long) fp - (long) sp;
  97.     if ( numberOfBytesSavedInContext != expectedBytesSavedInContext ){
  98.         cerr << "error: " << __FILE__ << ", line " << int(__LINE__) << "\n";
  99.         cerr << "numberOfBytesSavedInContext = " << int(numberOfBytesSavedInContext) << "\n";
  100.         cerr << "expectedBytesSavedInContext = " << int(expectedBytesSavedInContext) << "\n";
  101.         exit(1);
  102.     }
  103.     numberOfQuadsSavedInContext = numberOfBytesSavedInContext / 4;
  104.     }
  105. }
  106.  
  107. #ifdef UNDEF
  108. void
  109. HardwareContext::magicSwitchTo(HardwareContext *to)
  110. {
  111.     register long theSp asm("sp");
  112.     register long theFp asm("fp");
  113.     ALL_REGISTERS;
  114.     sp = theSp;
  115.     fp = theFp;
  116.     theSp = to -> sp;
  117.     theFp = to -> fp;
  118. }
  119. #else
  120. void
  121. HardwareContext::magicSwitchTo(HardwareContext *to)
  122. {
  123.     ALL_REGISTERS;
  124.     asm("    sw    $29,%0" : : "m" (sp));
  125.     asm("    sw    $30,%0" : : "m" (fp));
  126.     asm("    lw    $29,%0" : "=g" (to -> sp));
  127.     asm("    lw    $30,%0" : "=g" (to -> fp));
  128. }
  129. #endif
  130.  
  131. void
  132. HardwareContext::stackOverflow()
  133. {
  134.     register unsigned depth = stackBase - getSp();
  135.     if (stackMax < depth) {
  136.     stackMax = depth;
  137.     }
  138.     if ( stackMax >= stackSize ) {
  139.     cerr << "\nStack overflow\n";
  140.     cerr << " getSp() = " << hex(long(getSp()));
  141.     cerr << " and stackBase = " << hex(long(stackBase)) << "\n";
  142.     cerr << *this << "\n";
  143.     cerr << "Current task is \n";
  144.     cerr << *(CurrentThread());
  145.     cerr << "\n";
  146.     cerr.flush();
  147.     }
  148.     assert( stackMax < stackSize );
  149.     assert( *stackCheck == MagicStackMarker );
  150. }
  151.  
  152. //
  153. //    Unlike other architectures, the MIPS processor passes arguments
  154. //    in registers. Thus, startOff will assume that *this* is stored
  155. //    in $a0 -- this may not be true, because we're not causing a0,etc
  156. //    to be saved & restored. In general, compilers may save/restore
  157. //    the argument registers in other registers. Hence, this hack.
  158. //
  159. //    We have the new thread return to __magicReturnFunction with four
  160. //    arguments explicitly stored in the stack. We load the first of these
  161. //    two arguments, which is the value of *this* to be passed to the
  162. //    function addressed in the second argument. Clear?
  163. //
  164. extern "C" {
  165.  void __magicReturnFunction();
  166. };
  167.  
  168. asm("    .ent    __magicReturnFunction");
  169. asm("    .globl    __magicReturnFunction");
  170. asm("__magicReturnFunction:");
  171. asm("    lw    $4,0($30)");
  172. asm("    lw    $31,4($30)");
  173. asm("    j    $31");
  174. asm("    .end    __magicReturnFunction");
  175.  
  176. void
  177. HardwareContext::buildReturnFrame(void *returnThis, voidFuncP returnAddress)
  178. {
  179.     //
  180.     //    To build a thread, we return to the first address of startOff,
  181.     //    which will use the current FP & SP to build a local context,
  182.     //    and then call the user main.
  183.     //
  184.     //    startOff needs to have a valid frame. The return address for this
  185.     //    frame is NULL, since we never exit procedure startOff.
  186.     //
  187.     
  188.     stackCheck = (long *) stackBase;
  189.     register HardwareContextQuad **stack;
  190.     stack = (HardwareContextQuad **) stackBase;
  191.     HardwareContextQuad **FP[4];
  192.     HardwareContextQuad **SP[4];
  193.  
  194.     /////////////// FIRST FRAME
  195.     // space for four args
  196.     FP[0] = stack;
  197.     stack -= 2;
  198.     stackCheck = (long *) stack;
  199.     *(stack--) = (HardwareContextQuad *) MagicStackMarker;
  200.     SP[0] = stack;
  201.     *(stack--) = 0;            // return address
  202.  
  203.     // provide space for four args a0..a4 and put
  204.     // return address in space for a1, and this for that fcn
  205.     // in a0. __magicReturnFunction will read these from the stack
  206.     // and jump to the return address with *this* set properly.
  207.  
  208.     stack -= 2;
  209.     *(stack--) = (HardwareContextQuad *) returnAddress;
  210.     *(stack) = (HardwareContextQuad *) returnThis;
  211.  
  212.     /////////////// SECOND FRAME
  213.     FP[1] = stack;
  214.     stack -= (numberOfQuadsSavedInContext-1);    // leave space for ....
  215.     *(stack--) = (HardwareContextQuad *) FP[1];
  216.     *(stack) = (HardwareContextQuad *) __magicReturnFunction;
  217.     SP[1] = stack;
  218.  
  219.     fp = (HardwareContextQuad) FP[1];
  220.     sp = (HardwareContextQuad) SP[1];
  221.  
  222. #ifdef DEBUG
  223.     cerr << "[HardwareContext-mips] Build stack for " << hex(long(this)) << "\n";
  224.     cerr << "[HardwareContext-mips] FP[0] = " << hex(long(FP[0])) << "\n";
  225.     cerr << "[HardwareContext-mips] SP[0] = " << hex(long(SP[0])) << "\n";
  226.     cerr << "[HardwareContext-mips] FP[1] = " << hex(long(FP[1])) << "\n";
  227.     cerr << "[HardwareContext-mips] SP[1] = " << hex(long(SP[1])) << "\n";
  228. #endif
  229. }
  230.  
  231. void
  232. HardwareContext::classPrintOn(ostream& s)
  233. {
  234.     s << "[HardwareContext] Stack spans " << hex(long(stackEnd));
  235.     s << " to " << hex(long(stackBase));
  236.     s << " used is  " << (stackMax) << " of " << stackSize << "\n";
  237.     s << "[HardwareContext] fp = " << hex(long(fp));
  238.     s << " sp = " << hex(long(sp));
  239.     long p = *( (long *) fp );
  240.     s << " @@fp = " << hex(p) << "\n";
  241. }
  242.  
  243. static
  244. void PrintSingleStackFrame()
  245. {
  246. }
  247. @
  248.